package vn.gq.udv.utils.download;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.zip.GZIPInputStream;
import javax.net.ssl.HttpsURLConnection;
import org.json.JSONException;
import org.json.JSONTokener;
import vn.gq.udv.utils.Base64;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Base64InputStream;

public class Client extends AsyncTask<String, Integer, Object> {

	public static final String TAG = Client.class.getSimpleName();
	public static final int PROGRESS_DIALOG_STYLE = 0;
	
	private DataType dataType;
	private IClientListener listener;
	private int resultCode = 0;
	
	public Client() {
	}
	
	public Client(Context context) {
	}
	
	
	public void setProgressDialog(ProgressDialog dialog) {
	}
	
	public void download(String url, IClientListener listener) {
		download(url, DataType.NORMAL, listener);
	}
	
	public void download(String url, DataType type) {
		download(url, type, null);
	}
	
	public void download(String url, DataType type, IClientListener listener) {
		dataType = type;
		this.listener = listener;
		execute(url);
	}
	
	@Override
	protected void onPreExecute() {
		super.onPreExecute();
	}

	@Override
	protected Object doInBackground(String... urls) {
		String url = urls[0];
		HttpsURLConnection connection = null;
		StringBuilder sb = new StringBuilder();
		try {
			connection = (HttpsURLConnection) new URL(url).openConnection();
			connection.setRequestMethod("GET");
			connection.connect();
			int resultCode = connection.getResponseCode();
			if (resultCode == 200) {
				final int contentLength = connection.getContentLength();
				InputStream is = null;
				switch (dataType) {
					case GZIP:
						is = new GZIPInputStream(connection.getInputStream());
						break;
					case BASE64GZIP:
						is = new Base64InputStream(new GZIPInputStream(connection.getInputStream()), Base64.URL_SAFE);
						break;
					default:
						is = connection.getInputStream();
				}
				int byteRead = 0;
				byte[] buff = new byte[4096];
				int totalByteRead = 0;
				sb = new StringBuilder();
				while ((byteRead = is.read(buff)) != -1) {
					sb.append(new String(buff, 0, byteRead));
					totalByteRead += byteRead;
					publishProgress((int) totalByteRead*100/contentLength);
				}
			} else {
				throw new ClientException("HTTP ERROR CODE: "+String.valueOf(resultCode));
			}
			connection.disconnect();
		} catch (MalformedURLException e) {
			e.printStackTrace();
			resultCode = 1;
		} catch (IOException e) {
			e.printStackTrace();
			resultCode = 2;
		} catch (ClientException e) {
			e.printStackTrace();
			resultCode = 404;
			return null;
		}
		if (dataType.equals(DataType.JSON)) {
			try {
				return new JSONTokener(sb.toString()).nextValue();
			} catch (JSONException e) {
				e.printStackTrace();
				return null;
			}
		}
		return sb.toString();
	}

	@Override
	protected void onProgressUpdate(Integer... values) {
	}

	@Override
	protected void onPostExecute(Object result) {
		if (listener != null) {
			listener.onDone(result, resultCode);
		}
	}
	
	
	public interface IClientListener {
		void onDone(Object data, int resultCode);
	}
	
	
	public class ClientException extends Exception {
		
		private static final long serialVersionUID = 742671463682116289L;

		public ClientException() {
			
		}
		
		public ClientException(String detailMessage) {
			super(detailMessage);
		}
		
		public ClientException(String detailMessage, Throwable cause) {
			super(detailMessage, cause);
		}
		
	}
	
}
